home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccppcsrc.lha
/
vbcc
/
vlink
/
t_amigaos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
47KB
|
1,515 lines
/* $VER: vlink t_amigaos.c V0.6c (05.02.99)
*
* This file is part of vlink, a portable linker for multiple
* object formats.
* Copyright (c) 1997-99 Frank Wille
*
* vlink is freeware and part of the portable and retargetable ANSI C
* compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
* vlink may be freely redistributed as long as no modifications are
* made and nothing is charged for it. Non-commercial usage is allowed
* without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.6c (05.02.98) phx
* __ctors/__dtors for executables only.
* v0.6a (19.12.98) phx
* Support for little endian object file formats.
* v0.6 (24.10.98) phx
* Take base register section offset from FFFuncs.baseoff.
* v0.5f (08.10.98) phx
* The automatic constructor/destructor functions have to begin
* with __INIT or __EXIT to avoid conflicts with ANSI-C identifiers.
* v0.5e (05.10.98) phx
* Global symbols beginning with _INIT or _EXIT will create an
* entry into the constructor/destructor function pointer table.
* These tables can be addressed by using the symbols __ctors
* and __dtors (e.g. in the startup/cleanup code of a program).
* The priority of these functions may be defined by specifying
* a number behind the INIT/EXIT string. Example: _INIT_9_OpenLibs.
* Otherwise their priority defaults to 0 and they will be
* positioned in order of occurence.
* v0.5d (22.08.98) phx
* Faster memory allocation can be activated by #define FASTALLOC.
* v0.5c (08.07.98) phx
* ehf_lnksym():
* Target amigaehf supports the automatic generation of "@__name"
* pointer variables in ".tocd". @__name will not be created, if
* _name is undefined too. Then it's assumed to be a real unknown
* symbol reference.
* v0.5 (27.06.98) phx
* Target-specific linker symbol support: ados_lnksym(), ehf_lnksym(),
* ados_setlnksym(), ehf_setlnksym().
* Linker symbols currently supported by ADOS and EHF:
* _DATA_BAS_,_DATA_LEN_,_BSS_LEN_,_LinkerDB,__BSSBAS,__BSSLEN,
* __ctors,__dtors,__DATA_BAS,__DATA_LEN,__BSS_LEN,__RESIDENT.
* v0.4 (05.06.98) phx
* Support for Code-Bss and Data-Bss (small data) sections.
* New FFF targetlink(). Checks for __MERGED, _NOMERGE and
* unnamed sections.
* v0.3b (02.05.98) phx
* Creates a dummy code section, if an output file has no
* section at all.
* v0.3 (12.04.98) phx
* fwrite32() is now called as fwrite32be().
* Uses new addreloc() from targets.c.
* addxref() requires addend.
* Ignore absolute local symbols for object files and ignore
* absolute local and global symbols for executable files.
* v0.2 (07.03.98) phx
* Unnamed sections of an executable will always get different
* names, to avoid that they are linked together.
* HUNK_DREL32 must be treated as HUNK_RELOC32SHORT, if the
* input file is executable.
* Number of hunks in HUNK_HEADER was wrong, if resident library
* name is missing (which is always the case).
* v0.1 (27.02.98) phx
* First version that seems to link AmigaOS ADOS and EHF
* objects and libraries. Many common features, like linking
* sections together which have relative references, are
* still missing. Also, PowerPC-ELF32 support is about to come.
* v0.0 (02.12.97) phx
* File created.
*/
#if defined(ADOS) || defined(EHF)
#define T_AMIGAOS_C
#include "vlink.h"
#include "amigahunks.h"
#define BSSDEFAULTNAME "BSS"
#define EXT_IGNORE 0x100
struct HunkInfo {
uint8 *hunkbase; /* base address of amigaos/ehf file */
uint8 *hunkptr; /* current hunk data pointer */
long hunkcnt; /* remaining bytes in this file */
char *filename;
bool exec; /* executable file? */
};
struct XRefNode {
struct node n;
char *sym_name;
uint8 ref_type;
int noffsets;
struct list xreflist;
};
static int ados_identify(char*,uint8 *,unsigned long);
static int ehf_identify(char *,uint8 *,unsigned long);
static int identify(char *,uint8 *,unsigned long);
static void readconv(struct GlobalVars *,struct LinkFile *);
static unsigned long secbase(struct GlobalVars *,char *);
static uint8 cmpsecflags(uint8,uint8);
static struct Section *bssdefault(struct ObjectUnit *);
static int targetlink(struct GlobalVars *,struct LinkedSection *,
struct Section *);
static struct Symbol *ados_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void ados_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static struct Symbol *ehf_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void ehf_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static int get_xtors_pri(char *);
static void create_xdef(struct GlobalVars *,struct Section *,char *,
uint32,uint8,uint8);
static void create_xrefs(struct GlobalVars *,struct HunkInfo *,
struct Section *,char *,uint8,uint8);
static char *gethunkname(struct HunkInfo *);
static bool addlongrelocs(struct GlobalVars *,struct HunkInfo *,
struct Section *,uint8);
static bool addshortrelocs(struct GlobalVars *,struct HunkInfo *,
struct Section *,uint8);
static void init_hunkinfo(struct HunkInfo *,char *,uint8 *,unsigned long);
static uint32 skiphunk(struct HunkInfo *);
static void movehunkptr32(struct HunkInfo *,uint32);
static void movehunkptr16(struct HunkInfo *,uint32);
static void alignhunkptr(struct HunkInfo *);
static uint32 testword32(struct HunkInfo *);
static uint32 nextword32(struct HunkInfo *);
static uint16 nextword16(struct HunkInfo *);
static void writeobject(struct GlobalVars *,FILE *);
static void writeshared(struct GlobalVars *,FILE *);
static void writeexec(struct GlobalVars *,FILE *);
static void hunk_name_len(FILE *,char *);
static void hunk_name(FILE *,char *);
static int strlen32(char *);
static void reloc_hunk(FILE *,struct LinkedSection *,struct GlobalVars *,
uint8,uint32);
static void unsupp_relocs(struct LinkedSection *);
static void ext_refs(FILE *,struct LinkedSection *);
static void ext_defs(FILE *,struct LinkedSection *,uint8,uint8,uint32);
static void unsupp_symbols(struct LinkedSection *);
struct FFFuncs fff_amigaos = {
"amigaos",
ados_identify,
readconv,
secbase,
cmpsecflags,
bssdefault,
targetlink,
ados_lnksym,
ados_setlnksym,
writeobject,
writeshared,
writeexec,
0x7ffe,
NULL,
1 /* big endian */
};
struct FFFuncs fff_ehf = {
"amigaehf",
ehf_identify,
readconv,
secbase,
cmpsecflags,
bssdefault,
targetlink,
ehf_lnksym,
ehf_setlnksym,
writeobject,
writeshared,
writeexec,
0x7ffe,
NULL,
1 /* big endian */
};
/* Automagically create symbols in .tocd, which start with the */
/* following letters: */
static char ehf_addrsym[] = "@_";
static char *ados_symnames[] = {
/* PhxAss */ "_DATA_BAS_","_DATA_LEN_","_BSS_LEN_",
/* SAS/StormC */ "_LinkerDB","__BSSBAS","__BSSLEN","__ctors","__dtors",
/* DICE-C */ "__DATA_BAS","__DATA_LEN","__BSS_LEN","__RESIDENT"
};
#define PHXDB 0
#define PHXDL 1
#define PHXBL 2
#define SASPT 3
#define SASBB 4
#define SASBL 5
#define SASCT 6
#define SASDT 7
#define DICDB 8
#define DICDL 9
#define DICBL 10
#define DICRS 11
#define LAST_LNKSYM DICRS
/* automatic constructors and destructors */
static char vbcc_INIT[] = "__INIT";
static char vbcc_EXIT[] = "__EXIT";
static char xtors_objname[] = "INITEXIT"; /* unit name for con/destructors */
static bool exthunk,symhunk;
/*****************************************************************/
/* Read ADOS / EHF */
/*****************************************************************/
static int ados_identify(char *name,uint8 *p,